﻿
using GSOrganization.Core;
using System.Security.Cryptography;
using static Microsoft.AspNetCore.Razor.Language.TagHelperMetadata;

namespace GSOrganization.Application;

/// <summary>
/// 菜单管理服务
/// </summary>
//[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class SysMenuService : BaseService, ITransient, Furion.DynamicApiController.IDynamicApiController, ISysMenuService
{

    private readonly IRepository<SysMenuSysRoleSysOperation> _sysMenuSysRoleSysOperation;
    private readonly IRepository<SysMenu> _sysMenu;
    private readonly IRepository<SysRole> _sysRole;
    public SysMenuService(IRepository<SysMenu> repository, IRepository<SysRole> sysRole, IRepository<SysMenuSysRoleSysOperation> sysMenuSysRoleSysOperation)
    {

        _sysMenu = repository;
        _sysRole = sysRole;
        _sysMenuSysRoleSysOperation = sysMenuSysRoleSysOperation;
    }
    /// <summary>
    /// 获取单个实体
    /// </summary> 
    /// <param name="id">主键</param>
    /// <returns></returns>    
    public SysMenuOutput GetSysMenu(string id)
    {
        if (string.IsNullOrWhiteSpace(id))
        {
            return null;
        }
        var item = _sysMenu.Include(i => i.Parent).FirstOrDefault(w => w.IsDel == false && w.Id == id);
        var entity = item.Adapt<SysMenuOutput>();
         
        return entity;
    }
    /// <summary>
    /// 创建
    /// </summary>
    /// <param name="entity">一个实体</param>
    /// <returns>是否成功</returns>
    [Microsoft.AspNetCore.Mvc.HttpPost]
    public ResponseModel CreateSysMenu(SysMenuOutput entity)
    {
        //创建,校验       
        var item = entity.Adapt<SysMenu>();

        item.Id = Result.GetNewId();
        //item.CreateUserId = entity.CurrentId;

        _sysMenu.Insert(item);

        var ds = _sysMenu.SaveNow();
        return ResponseModel.Succeed(ds);

    }
    /// <summary>
    /// 编辑
    /// </summary>
    /// <param name="entity">一个实体</param>
    /// <returns>是否成功</returns>
    [HttpPost]
    public ResponseModel EditSysMenu(SysMenuOutput entity)
    {
        var item = _sysMenu.FirstOrDefault(f => f.Id == entity.Id);
        if (item == null)
        {
            return ResponseModel.Fail("数据不存在");
        }
        //校验     
        entity.Adapt(item);

        var ds = _sysMenu.SaveNow();
        return ResponseModel.Succeed(ds);
    }
    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpPost]
    public ResponseModel DeleteMenu(string id)
    {
        if (!string.IsNullOrWhiteSpace(id))
        {

            var item = _sysMenu.FirstOrDefault(a => a.Id == id);
            if (item != null)
            {
                item.IsDel = true;
                item.UpdateUserId = UserId;
                item.UpdatedTime = DateTime.Now;

                _sysMenu.UpdateNow(item);


                var log = new SysLogInput() { Result = "成功", MenuId = "菜单管理", Message = "删除" + item.Title + ",id为" + id };
                LogModels.WriteLog(log);

            }
            else
            {
                return ResponseModel.Fail("对不起，删除的数据不存在");
            }

        }
        else
        {
            return ResponseModel.Fail("主键不能为空");
        }

        return ResponseModel.SucceedDelete();
    }


    /// <summary>
    /// 列表
    /// </summary>
    /// <returns>列表返回值</returns>
    [HttpPost]
    //[NonUnify]
    public ResponseModel<List<SysMenuIndexOutput>> DataSysMenu()
    {
        var fasd = UserId;
        var itemCreateUserId = CurrUser;

        //根据用户名，获知角色，然后获取菜单

        var systemMenuEntities = _sysMenu.Where(w => w.IsDel == false).ToList();

        //var menuNeed =
        //            (
        //            from m2 in systemMenuEntities
        //            select m2
        //            ).Select(m2=> new SysMenuIndexOutput()
        //            {
        //                id = m2.Id,
        //                name = m2.Title,
        //                pid = m2.ParentId
        //            }).Distinct().OrderBy(o => o.pid).OrderBy(o => o.Sort).ToList();

 

        //return new ResponseModel<List<SysMenuIndexOutput>>
        //{
        //    count = menuNeed.Count,
        //    data = menuNeed
        //};
         

        List<SysMenu> menuNeed =
                    (
                    from m2 in systemMenuEntities
                    select m2
                    ).Distinct().OrderBy(o => o.ParentId).OrderBy(o => o.Sort).ToList();


        var rootNode = new SysMenuIndexOutput()
        {
        };
        //根据父节点将子节点递归
        GetTree(menuNeed.ToArray(), rootNode);


        var total = menuNeed.Count();

        return new ResponseModel<List<SysMenuIndexOutput>>
        {
            count = total,
            data = rootNode.children.ToList()
        };
    }
    /// <summary>
    /// 菜单的列表，递归处理数据
    /// </summary>
    /// <param name="systemMenuEntities"></param>
    /// <param name="rootNode"></param>
    protected static void GetTree(SysMenu[] systemMenuEntities, SysMenuIndexOutput rootNode)
    {
        if (systemMenuEntities == null || systemMenuEntities.Count() <= 0)
        {
            return;
        }

        var childreDataList = systemMenuEntities.Where(p => p.ParentId == rootNode.Id);
        if (childreDataList != null && childreDataList.Count() > 0)
        {
            rootNode.children = new List<SysMenuIndexOutput>();

            foreach (var item in childreDataList)
            {
                var treeNode = new SysMenuIndexOutput()
                {
                    Id = item.Id,
                    Status = item.Status,
                    Href = item.Href,
                    Name = item.Title,
                    Icon = item.Icon,
                    Sort = item.Sort
                };
                rootNode.children.Add(treeNode);
                 
                GetTree(systemMenuEntities, treeNode);
            }
        }
    }

    public MenusInfoResultDTO SystemMenuByRole(List<string> roleIds)
    {
        var systemMenuEntities = _sysMenu.Where(w => w.IsDel == false);
        List<SysMenu> menuNeed =
                    (
                    from m2 in systemMenuEntities
                    from f in m2.SysMenuSysRoleSysOperation

                    where roleIds.Any(a => a == f.SysRoleId) && f.SysOperationId == null
                    select m2
                    ).Distinct().ToList();//根据用户名，获知角色，然后获取菜单
        menuNeed = menuNeed.OrderBy(o => o.Sort).ToList();
        SystemMenu rootNode = new SystemMenu()
        {
            id = "",//此处要跟数据库里面的数据保持一致
            icon = "",
            href = "",
            title = "根目录",
        };
        List<SysMenu> search = new List<SysMenu>();
        foreach (var item in menuNeed)
        {
            search.Add(item);
        }
        //寻找子节点的父节点
        foreach (var item in search)
        {

            GetParentId(menuNeed, systemMenuEntities, item);
        }
        //根据父节点将子节点递归
        GetTreeNodeListByNoLockedDTOArray(menuNeed.ToArray(), rootNode);

        MenusInfoResultDTO menusInfoResultDTO = new MenusInfoResultDTO();
        var sysMenus = new List<SystemMenu>();
        sysMenus.Add(rootNode);
        menusInfoResultDTO.menuInfo = sysMenus;

        return menusInfoResultDTO;
    }
    /// <summary>
    /// 根据用户名，获知角色，然后获取菜单
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public MenusInfoResultDTO SystemMenu()
    {
        //
        string personId = UserId;

        var roleIds =
                   (
                   from r in _sysRole.Where(w => w.IsDel == false)
                   from p in r.SysPerson
                   where p.Id == personId
                   select r.Id
                   ).ToList();

        var systemMenuEntities = _sysMenu.Where(w => w.IsDel == false);
        List<SysMenu> menuNeed =
                    (
                    from m2 in systemMenuEntities
                    from f in m2.SysMenuSysRoleSysOperation

                    where roleIds.Any(a => a == f.SysRoleId) && f.SysOperationId == null
                    select m2
                    ).Distinct().ToList();//此方法由临海人(qq:1012999282)提供
        menuNeed = menuNeed.OrderBy(o => o.Sort).ToList();
        SystemMenu rootNode = new SystemMenu()
        {
            id = "",//此处要跟数据库里面的数据保持一致
            icon = "",
            href = "",
            title = "管理系统",
        };
        List<SysMenu> search = new List<SysMenu>();
        foreach (var item in menuNeed)
        {
            search.Add(item);
        }
        //寻找子节点的父节点
        foreach (var item in search)
        {

            GetParentId(menuNeed, systemMenuEntities, item);
        }
        //根据父节点将子节点递归
        GetTreeNodeListByNoLockedDTOArray(menuNeed.ToArray(), rootNode);

        MenusInfoResultDTO menusInfoResultDTO = new MenusInfoResultDTO();
        var sysMenus = new List<SystemMenu>();
        sysMenus.Add(rootNode);
        menusInfoResultDTO.menuInfo = sysMenus;
        menusInfoResultDTO.logoInfo = new LogoInfo();
        menusInfoResultDTO.homeInfo = new HomeInfo();

        return menusInfoResultDTO;
    }
    protected void GetParentId(List<SysMenu> menuNeed, IQueryable<SysMenu> systemMenuEntities, SysMenu menu)
    {
        if (string.IsNullOrWhiteSpace(menu.ParentId))
        {
            return;
        }
        else
        {
            var a = menuNeed.FirstOrDefault(w => w.Id == menu.ParentId);
            if (a == null)
            {
                var father = systemMenuEntities.FirstOrDefault(w => w.Id == menu.ParentId);
                menuNeed.Add(father);
                GetParentId(menuNeed, systemMenuEntities, father);
            }



        }


    }

    /// <summary>
    /// 角色-授权，获取所有的菜单
    /// </summary>
    /// <param name="sysroleid"></param>
    /// <returns></returns>
    public ResponseModel<List<SystemTree>> SystemTree(string sysroleid)
    {
        //根据用户名，获知角色，然后获取菜单


        var systemMenuEntities = _sysMenu.Where(w => w.IsDel == false);

        var rootNode = new SystemTree()
        {
            id = "",//此处要跟数据库里面的数据保持一致
            icon = "",
            spread = true
        };

        //根据 角色id，然后获取菜单
        var collection = _sysMenuSysRoleSysOperation
            .Where(w => w.IsDel == false && w.SysRoleId == sysroleid)
            .Select(s => s.SysMenuId)
            .ToList();

        GetTreeNodeList(systemMenuEntities.ToArray(), rootNode, collection);


        return new ResponseModel<List<SystemTree>>() { data = rootNode.children };

    }

    /// <summary>
    /// 首页左侧的菜单，递归处理数据
    /// </summary>
    /// <param name="systemMenuEntities"></param>
    /// <param name="rootNode"></param>
    protected static void GetTreeNodeListByNoLockedDTOArray(SysMenu[] systemMenuEntities, SystemMenu rootNode)
    {
        if (systemMenuEntities == null || systemMenuEntities.Count() <= 0)
        {
            return;
        }
        if (string.IsNullOrEmpty(rootNode.id))
        {
            var childreDataList = systemMenuEntities.Where(p => p.ParentId == rootNode.id || p.ParentId == null);
            if (childreDataList != null && childreDataList.Count() > 0)
            {
                rootNode.child = new List<SystemMenu>();

                foreach (var item in childreDataList)
                {
                    SystemMenu treeNode = new SystemMenu()
                    {
                        id = item.Id,
                        icon = item.Icon,
                        href = item.Href,
                        title = item.Title,
                    };
                    rootNode.child.Add(treeNode);
                }

                foreach (var item in rootNode.child)
                {
                    GetTreeNodeListByNoLockedDTOArray(systemMenuEntities, item);
                }
            }
        }
        else
        {
            var childreDataList = systemMenuEntities.Where(p => p.ParentId == rootNode.id);
            if (childreDataList != null && childreDataList.Count() > 0)
            {
                rootNode.child = new List<SystemMenu>();

                foreach (var item in childreDataList)
                {
                    SystemMenu treeNode = new SystemMenu()
                    {
                        id = item.Id,
                        icon = item.Icon,
                        href = item.Href,
                        title = item.Title,
                    };
                    rootNode.child.Add(treeNode);
                }

                foreach (var item in rootNode.child)
                {
                    GetTreeNodeListByNoLockedDTOArray(systemMenuEntities, item);
                }
            }
        }

    }
    /// <summary>
    /// 角色-授权，获取所有的菜单，递归处理数据
    /// </summary>
    /// <param name="systemMenuEntities"></param>
    /// <param name="rootNode"></param>
    /// <param name="collection"></param>
    protected static void GetTreeNodeList(SysMenu[] systemMenuEntities, SystemTree rootNode, List<string> collection)
    {
        if (systemMenuEntities == null || systemMenuEntities.Count() <= 0)
        {
            return;
        }
        if (string.IsNullOrEmpty(rootNode.id))
        {
            var childreDataList = systemMenuEntities.Where(p => p.ParentId == rootNode.id || p.ParentId == null);

            if (childreDataList != null && childreDataList.Count() > 0)
            {
                rootNode.children = new List<SystemTree>();

                foreach (var item in childreDataList)
                {
                    var treeNode = new SystemTree()
                    {
                        id = item.Id,
                        icon = item.Icon,

                        title = item.Title,
                        spread = true
                    };
                    if (collection.Contains(item.Id))
                    {
                        treeNode.@checked = true;
                    }
                    rootNode.children.Add(treeNode);
                }

                foreach (var item in rootNode.children)
                {
                    GetTreeNodeList(systemMenuEntities, item, collection);
                }
            }
        }
        else
        {
            var childreDataList = systemMenuEntities.Where(p => p.ParentId == rootNode.id);
            if (childreDataList != null && childreDataList.Count() > 0)
            {
                rootNode.children = new List<SystemTree>();

                foreach (var item in childreDataList)
                {
                    var treeNode = new SystemTree()
                    {
                        id = item.Id,
                        icon = item.Icon,

                        title = item.Title,
                        spread = true
                    };
                    if (collection.Contains(item.Id))
                    {
                        treeNode.@checked = true;
                    }
                    rootNode.children.Add(treeNode);
                }

                foreach (var item in rootNode.children)
                {
                    GetTreeNodeList(systemMenuEntities, item, collection);
                }
            }
        }

    }

}



